#include <array>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <map>
#include <optional>
#include <sstream>
#include <string>
#include <vector>

#include <unistd.h>

#define EXAMPLE 15

#define Stringify(a) Stringify2((a))
#define Stringify2(a) #a
#define SCALE (100)
#define NEWNUM (4096 * SCALE)

#if EXAMPLE == 0
#define T int
#define OP(obj, count) (obj) = count
// int: 4

#elif EXAMPLE == 1
#define T double
#define OP(obj, count) (obj) = count
// double: 8

#elif EXAMPLE == 2
struct S {
    double d1;
    char c1;
    double d2;
};
#define T S
#define OP(obj, count) (obj).d1 = count
// S: 24

#elif EXAMPLE == 3
#define T std::vector<int>
#define OP(obj, count) for (auto i = 0; i < count; i++) obj.push_back(i)
// std::vector<int>: 0 24
// std::vector<int>: x 40 + 4 * x

#elif EXAMPLE == 4
struct S {
    double d1;
    double d2;
    double d3;
    double d4;
};
#define T std::vector<S>
#define OP(obj, count) for (auto i = 0; i < count; i++) obj.push_back({})
// std::vector<S>: 0 24
// std::vector<S>: 4 168 = 40 + 4 * 32

#elif EXAMPLE == 5
#define T std::string
#define OP(obj, count) for (auto i = 0; i < count; i++) obj.push_back(i)
// std::string: 0 32
// std::string: x(>= 16) 48 + x

#elif EXAMPLE == 6
#define T std::string
#define OP(obj, count) obj = std::string(count, ' ')
// std::string: 0 32
// std::string: 16 64
// std::string: x(>= 24) 80 + (x - 24) / 16 * 16

#elif EXAMPLE == 7
#define T std::vector<int>
#define OP(obj, count) obj.reserve(count); for (auto i = 0; i < count; i++) obj[i] = i
// std::vector<int>: 0 24
// std::vector<int>: 1 56
// std::vector<int>: x(>= 7) 32 + x * 4

#elif EXAMPLE == 8
#define T std::map<int, int>
#define OP(obj, count) for (auto i = 0; i < count; i++) obj[i] = i
// (std::map<int, int>): 0 48
// (std::map<int, int>): x(>= 1) 48 + 48 * x
// 48 = 4 + 4 + 40

#elif EXAMPLE == 9
struct S {
    double d1;
    double d2;
    double d3;
    double d4;
};
#define T std::map<int, S>
#define OP(obj, count) for (auto i = 0; i < count; i++) obj[i] = {}
// (std::map<int, S>): 0 48
// (std::map<int, S>): x(>= 1) 48 + 80 * x
// 80 = 4 + 4 + 32 + 40

#elif EXAMPLE == 10
struct S {
    double d1;
    double d2;
    double d3;
    double d4;
};
#define T std::map<std::string, S>
#define OP(obj, count) for (auto i = 0; i < count; i++) { std::stringstream ss; ss << i; obj[ss.str()] = {}; }
// (std::map<std::string, S>): 0 48
// (std::map<std::string, S>): x(>= 1) 48 + 112 * x
// 112 = 4(8) + 32 + 32 + 40

#elif EXAMPLE == 11
struct S {
    double d1;
    double d2;
    double d3;
    double d4;
};
#define T std::map<double, S>
#define OP(obj, count) for (auto i = 0; i < count; i++) { obj[i + 0.5] = {}; }
// (std::map<std::string, S>): 0 48
// (std::map<std::string, S>): x(>= 1) 48 + 80 * x
// 80 = 8 + 32 + 40

#elif EXAMPLE == 12
struct K {
    int i1;
    int i2;
    int i3;
    int i4;
    int i5;
    int i6;
    int i7;
    int i8;
    bool operator <(const struct K &rhs) const
    {
        return i1 < rhs.i1;
    }
};
struct S {
    double d1;
    double d2;
    double d3;
    double d4;
};
#define T std::map<K, S>
#define OP(obj, count) for (auto i = 0; i < count; i++) { obj[{.i1 = i}] = {}; }
// (std::map<std::string, S>): 0 48
// (std::map<std::string, S>): x(>= 1) 48 + 112 * x
// 112 = 8? + 32 + 32 + 40

#elif EXAMPLE == 13
struct K {
    int i1;
    bool operator <(const struct K &rhs) const
    {
        return i1 < rhs.i1;
    }
};
struct S {
    double d1;
    double d2;
    double d3;
    double d4;
};
#define T std::map<K, S>
#define OP(obj, count) for (auto i = 0; i < count; i++) { obj[{.i1 = i}] = {}; }
// (std::map<std::string, S>): 0 48
// (std::map<std::string, S>): x(>= 1) 48 + 80 * x
// 80 = 8? + 4(8) + 32 + 40

#elif EXAMPLE == 14
struct K {
    int i1;
    std::array<char, 5> cs;
    bool operator <(const struct K &rhs) const
    {
        return i1 < rhs.i1;
    }
};
struct S {
    double d1;
    double d2;
    double d3;
    double d4;
};
#define T std::map<K, S>
#define OP(obj, count) for (auto i = 0; i < count; i++) { obj[{.i1 = i}] = {}; }
// (std::map<std::string, S>): 0 48
// (std::map<std::string, S>): x(>= 1, K <= 8) 48 + (40 + K + V) * x
// (std::map<std::string, S>): x(>= 1, K > 8) 48 + (48 + K + V) * x
// 96 = 9(16) + 32 + 48

#elif EXAMPLE == 15
struct S {
    double d1;
    double d2;
    double d3;
    double d4;
};
#define T std::optional<S>
#define OP(obj, count) if (count) obj = S{};
// (std::optional<S>): 0 40.02 40

#endif

int GetUsage(int)
{
    return 4;
}

template<class TT>
int GetUsage(const std::vector<TT> &v)
{
    return v.capacity() ? 40 + v.capacity() * sizeof(TT) : 24;
}

template<class K, class V>
int GetUsage(const std::map<K, V> &m)
{
    if (sizeof(K) <= 8) {
        return 48 + (40 + sizeof(K) + sizeof(V)) * m.size();
    } else {
        return 48 + (48 + sizeof(K) + sizeof(V)) * m.size();
    }
}

int StringToInt(const char *str)
{
    int count = 0;
    for (const char *p = str; *p; p++) {
        if (!('0' <= *p && *p <= '9')) {
            break;
        }
        count = count * 10 + (*p - '0');
    }
    return count;
}

void IntToString(char *str, int number)
{
    assert(number >= 0);
    while (*str) str++;

    int num10 = 1;
    while (number >= num10 * 10) {
        num10 *= 10;
    }

    while (num10) {
        *str++ = number / num10 + '0';
        number %= num10;
        num10 /= 10;
    }
    *str = 0;
}

int main(int argc, char **argv)
{
    if (argc <= 1) {
        return 0;
    }

    int count = StringToInt(argv[1]);
    int j = 0;

    char cmd[64] = "cat /proc/";
    IntToString(cmd, getpid());
    strcat(cmd, "/stat | sed 's@ @\\n@g' | sed -n '24p'");
    char buf[4096];
    FILE *fp = nullptr;
    fp = popen(cmd, "r");
    fread(buf, 1, sizeof(buf), fp);
    pclose(fp);
    auto pre = StringToInt(buf);

    auto obj = new std::array<T, NEWNUM>{};
    for (j = 0; j < NEWNUM; j++) {
        OP((*obj)[j], count);
    }

    fp = popen(cmd, "r");
    fread(buf, 1, sizeof(buf), fp);
    pclose(fp);
    auto post = StringToInt(buf);
    printf(Stringify(T) ": %d %d.%02d %zu\n", count, (post - pre) / SCALE, (post - pre) % SCALE, sizeof(T));
    return 0;
}
